home *** CD-ROM | disk | FTP | other *** search
- #pragma option -zAINIT // change code segment class to 'INIT'
- // so that it comes after the stack and
- // it can be released when going resident.
-
- #pragma option -zFINIT // change far data segment class to 'INIT'
- // for same reason.
-
- #pragma option -zEINIT_DATA // also force all far data to go to one
- // segment (just for this module)
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <process.h>
- #include <dos.h>
- #include "vectors.h"
-
- #define puts(a) jputs (a) // cause the real puts() adds a newline dammit!
- #define ENDL() {if (verbose) putchar ('\n');}
-
- char far hex_buffer[5]; // used by hex();
-
- char far init_title[] = "JLink Version 1.0 Copyright (c) 1992 by Borland International\n";
- char far init_resident[] = "TSR is resident\n";
- char far init_unloaded[] = "TSR is unloaded\n";
- char far init_v_psp[] = "\nPSP:";
- char far init_is_loaded[] = "\aERROR: JLink is already loaded, exiting...\n";
- char far init_not_loaded[] = "\aERROR: JLink is not loaded, exiting...\n";
- char far init_e_unloading[] = "\aERROR: could not unload because of INT-";
- char far init_bad_param[] = "\aERROR: invalid parameter: ";
- char far init_hose_bad[] = "\aERROR: extream hose error!\n";
- char far init_bad_speed[] = "WARNING: invalid speed selected, resetting to default.\n";
-
- char far init_help[] =
- "\nUsage: JLINK [options]\n\n"
- " -? Prints this help screen\n"
- // " -Ffilename Sets the filename to log to (default = test.dat)\n"
- " -R Removes the TSR from memory\n"
- " -Sxxx Sets the speed of updating (in 18ths sec)\n"
- " -V Verbose mode (-V- quite mode)\n";
-
- int far verbose = 1; // 0 = none, 1 = regular, 2 = extra strength
-
- char far fname[81] = "TEST.DAT";
-
- void _restorezero (void); // from the BORLAND startup code
- int is_there (void); // see's if we are loaded already
- void hook_em_danno (void); // gets ready to go resident
- char *byte (BYTE); // converts a byte into a hex string
- char *hex (WORD); // converts an int to a string in hex
- void _hex (WORD); // helper for hex()
- void jputs (char *s); // my own string printing function
- int unload (void); // unload's the resident TSR (if possible)
- void back_here (void); // destination of the 'DOS unload' rollercoaster
-
- int main (int argc, char *argv[])
- {
- int x = 1;
- WORD temp;
-
- if (argv[1][0] != ':') // do title?
- puts (init_title);
- else
- x = 2, verbose = 0;
-
- for (;x < argc; x++)
- {
- if (argv[x][0] == '-' || argv[x][0] == '/')
- {
- switch (toupper (argv[x][1]))
- {
- case 'H':
- case '?':
- puts (init_help);
- return 3;
-
- case 'R':
- if (unload ())
- return 4;
- else
- return 5;
-
- case 'V':
- verbose = 2;
- if (argv[x][2] == '-')
- verbose = 0;
- break;
-
- case 'S':
- temp = atoi (&argv[x][2]);
- if (temp == 0 || temp > 255)
- puts (init_bad_speed);
- else
- {
- _8_max = temp;
- }
- break;
- /*
- case 'F':
- strcpy (fname, &(argv[x][2]));
- break;
- */
- default: goto bad_param;
- }
- }
- else
- {
- bad_param:
- puts (init_bad_param);
- puts (argv[x]);
- ENDL();
- return 2;
- }
- }
-
- if (is_there ())
- {
- puts (init_is_loaded);
- return 1;
- }
- else
- {
- if (verbose == 2)
- {
- puts (init_v_psp);
- puts (hex (_psp));
- ENDL();
- }
-
- /*
- if ((file = fopen (fname, "wt")) == NULL)
- {
- perror (fname);
- return 7;
- }
- */
- puts (init_resident);
-
- hook_em_danno ();
-
- keep(0, (_SS - _psp) + 1);
- }
- return 0;
- }
-
- int is_there (void)
- {
- _AH = MY_ID;
- _AL = DETECT_CMD;
- geninterrupt (0x2F);
- if (_AX == 0xFFFF)
- return 1;
-
- return 0;
- }
-
- void hook_em_danno ()
- {
- WORD s,o;
-
- _AH = 0x34; // UNDOC DOS get inDOS pointer
- geninterrupt (0x21);
- s = _ES;
- o = _BX;
-
- indos = MK_FP (s,o); // be nice to DOS so it doesn't "barf" on us.
-
-
- old_8 = getvect (0x8);
- old_2F = getvect (0x2F);
- old_28 = getvect (0x28);
-
- setvect (0x8, new_8);
- setvect (0x2F, new_2F);
- setvect (0x28, new_28);
- }
-
- char *hex (WORD x)
- {
- _ES = FP_SEG (hex_buffer);
- _DI = FP_OFF (hex_buffer);
- _AX = x;
- _hex (_AH); // upper byte
- _AX = x;
- _hex (_AL); // lower byte
-
- hex_buffer[4] = 0;
- return hex_buffer;
- }
-
- char *byte (BYTE x)
- {
- _ES = FP_SEG (hex_buffer);
- _DI = FP_OFF (hex_buffer);
- _AL = x;
- _hex (_AL); // upper byte
-
- hex_buffer[2] = 0;
- return hex_buffer;
- }
-
- void _hex (WORD x)
- {
- _AX = x;
- asm {
- mov ah, al
- and al, 0fh
- mov cl, 4
- shr ah, cl
- // ah has MSD
- // al has LSD
- or ax, 3030h
- xchg al, ah
-
- cmp ah, 39h
- ja _fix_ah
- }
- _fix_ah_ret:
- asm {
- cmp al, 39h
- ja _fix_al
-
- }
- write_it:
- asm {
- stosw
- jmp hex_done
- }
- _fix_al:
- asm {
- sub al, 30h
- add al, 'A' - 10
- jmp write_it
- }
- _fix_ah:
- asm {
- sub ah, 30h
- add ah, 'A' - 10
- jmp _fix_ah_ret
- }
- hex_done:
-
- }
-
- void jputs (char *s)
- {
- if (!verbose)
- return;
-
- while (*s)
- {
- _AL = *s;
- geninterrupt (0x29); // DOS fast putchar
- if (*s == '\n')
- {
- _AL = 13;
- geninterrupt (0x29);
- }
- s++;
- }
- }
-
- int unload (void)
- {
- WORD tsrpsp, code;
- WORD far *p;
-
- if (!is_there())
- {
- puts (init_not_loaded);
- return 1;
- }
-
- _restorezero (); // "buckle up, this could be a rough ride!"
-
- _AH = MY_ID;
- _AL = UNLOAD_CMD;
- geninterrupt (0x2F); // make TSR unhook it's vects
-
- if (_AX != 0xFFFF)
- {
- code = _CX; // int vect that could not be unloaded
- puts (init_e_unloading);
- puts (byte (code));
- ENDL();
- _AX = 0x4C04;
- geninterrupt (0x21); // exit out quick
- }
-
-
- tsrpsp = _BX;
-
- p = MK_FP (tsrpsp, 0x0A); // Location the TSR returns to when unloaded.
- // this location in a PSP usually points
- // back to command.com who loaded it. We,
- // however, are sneakier than DOS realizes and
- // we make this location point back to us.
- // (Well, let's rightfuly give credit to
- // Mr. Schulman for this one) <grin>
-
- p[0] = FP_OFF (back_here);
- p[1] = FP_SEG (back_here);
-
- _AH = 0x50; // UNDOC DOS Set PSP segment
- _BX = tsrpsp;
- geninterrupt (0x21); // make our TSR the current process
-
- _AX = 0x4C00; // terminate current (TSR) process
- geninterrupt (0x21); // "remember to keep your hands up and
- // scream the whole way!"
-
- // NOTE: we should never get here, but instead end up in back_here()
-
- puts (init_hose_bad); // "Toto, we're not in Kansas anymore!"
- return 0;
- }
-
- void _loadds back_here () // use _loadds since DOS has blown away our
- // DS value.
- {
- // If we get here, then the TSR was successfully unloaded, and we should
- // step out of our cock-pit and kiss the ground (or at least give thanks
- // to the DOS gods. Sacrafice a diskette or something. <double grin> )
-
- // and now for something completely different, we must switch back
- // to our PSP and exit ourselves
-
- _AH = 0x50; // UNDOC DOS Set PSP segment
- _BX = _psp;
- geninterrupt (0x21); // Aaahhh, much better.
-
- puts (init_unloaded);
-
- _AX = 0x4C06;
- geninterrupt (0x21); // This time it's for real.
- }
-
-